/**
 * @Author: Jiang Zhongxun
 * @Date: 2024-10-06 20:26:21
 * @FilePath: /Socket/practiceProject/src/sys/adminSys.c
 * @Description: 管理端接口。包含：人工查验审核、查询操作记录、修改用户密码。
 * @Copyright (c) 2024 by 蒋仲勋, All Rights Reserved.
 */
#include "../../include/server/adminSys.h"
#include "../../include/db/dbDefinition.h"
#include "../../include/db/dbOperation.h"
#include "../../include/utils/utils.h"

/**
 * @description: 人工查验审核
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @param {CheckStatus} checkStatus 查验状态
 * @return {*} 成功返回0，失败返回非0的数
 */
int manualAudit(sqlite3 *db)
{
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "checkInfo";
    char message[128] = {0};
    int ret;
    int itemNum; // 选择的需要人工查验的记录编号
    int status;  // 人工查验设置的查验状态
    sprintf(sql, "SELECT * FROM %s WHERE (checkStatus = %d OR checkStatus = %d) AND isDelete = %d;",
            CHECK_TABLE_NAME, NOTCHECKED, CHECKFAILED, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    if (0 == row)
    {
        printf("没有查到任何查验信息!\n");
    }
    else
    {
        // 悉数打印 row 行记录的数据
        int i, j;
        printf("=============================================== XX 海关进出口智慧查验平台 ================================================\n\n");
        for (i = 0; i <= row; i++)
        {
            for (j = 0; j < column; j++)
            {
                // 如果是 checkStatus 列
                if (j == 4)
                {
                    // 判断 checkStatus 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("未查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("已查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "2"))
                    {
                        printf("已驳回\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else if (j == 5)
                {
                    // 判断 checkType 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("系统自动查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("人工手动查验\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else
                {
                    // 对于非 checkStatus 和 checkType 列，直接输出原值
                    printf("%s\t", result[i * column + j]);
                    // fflush(stdout); // 强制刷新缓冲区
                }
            }
            printf("\n");
            printf("-------------------------------------------------------------------------------------------------------------------------\n");
        }
        printf("\n                                   Copyright (c) 2024 by 蒋仲勋, All Rights Reserved                          \n");
        printf("=========================================================================================================================\n\n");
        printf("请选择要进行人工查验审核的记录: ");
        scanf("%d", &itemNum);
        printf("请设置人工查验审核状态【0:未查验 1:已查验 2:已驳回】: ");
        scanf("%d", &status);
        bzero(sql, sizeof(sql));
        sprintf(sql, "UPDATE %s SET checker = '%s', checkStatus = %d, checkType = %d, \
        updateTime = dateTime('now', 'localtime') WHERE checkId = %d;",
                CHECK_TABLE_NAME, "root", status, MANUALCHECK, itemNum);
        ret = execOperate(db, sql, &errmsg, operationName);
        if (0 != ret)
        {
            fprintf(stderr, "记录【%d】执行人工查验审核失败! %s\n", itemNum, errmsg ? errmsg : "通用的SQL增删改操作error");
            return -1;
        }
        else
        {
            printf("记录【%d】执行人工查验审核成功!\n", itemNum);
            // 记录日志
            snprintf(message, sizeof(message), "管理员人工审核【%d】为【%s】", itemNum,
                     status == 0 ? "未查验" : status == 1 ? "已查验"
                                                          : "已驳回");
            logToLogInfoTable(db, OPERATELOG, message);
        }
    }
    return 0;
}

/**
 * @description: 查询操作记录，倒叙展示【考虑分页展示】
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @return {*} 成功返回0，失败返回非0的数
 */
int queryOperationRecord(sqlite3 *db)
{
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "userInfo";
    sprintf(sql, "SELECT * FROM %s WHERE isDelete = %d ORDER BY createTime DESC;", LOG_TABLE_NAME, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    if (0 == row)
    {
        printf("没有查到任何日志信息!\n");
    }
    else
    {
        // 悉数打印 row 行记录的数据
        int i, j;
        printf("========================================== XX 海关进出口智慧查验平台 ===========================================\n\n");
        for (i = 0; i <= row; i++)
        {
            for (j = 0; j < column; j++)
            {
                // 如果是 logType 列
                if (j == 2)
                {
                    // 判断 logType 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("系统日志\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("操作日志\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else
                {
                    // 对于非 logType 列，直接输出原值
                    printf("%s\t", result[i * column + j]);
                    // fflush(stdout); // 强制刷新缓冲区
                }
            }
            printf("\n");
            printf("-------------------------------------------------------------------------------------------------------------\n");
        }
        printf("\n                                   Copyright (c) 2024 by 蒋仲勋, All Rights Reserved                          \n");
        printf("===============================================================================================================\n\n");
    }
    return 0;
}

/**
 * @description: 管理员修改用户密码
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @return {*} 成功返回0，失败返回非0的数
 */
int changeUserPasswd(sqlite3 *db)
{
    char userName[20] = {0};
    char newPasswd[20] = {0};
    printf("要修改密码的用户: ");
    scanf("%s", userName);
    printf("要修改成的密码: ");
    scanf("%s", newPasswd);
    // 判断要修改密码的用户是否存在，存在则修改，不存在则给出提示
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "userInfo";
    char message[128] = {0};
    int ret;
    sprintf(sql, "SELECT userName, passwd FROM %s WHERE userName = '%s' AND isDelete = %d;", USER_TABLE_NAME, userName, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    // 查询返回的结果集中行数为0，表示不存在要修改密码的用户
    if (0 == row)
    {
        fprintf(stderr, "要修改密码的用户名【%s】不存在!\n", userName);
    }
    // 存在则修改密码
    else
    {
        bzero(sql, sizeof(sql));
        sprintf(sql, "UPDATE %s SET passwd = '%s' WHERE userName = '%s';", USER_TABLE_NAME, newPasswd, userName);
        ret = execOperate(db, sql, &errmsg, operationName);
        if (0 != ret)
        {
            fprintf(stderr, "用户【%s】密码修改失败! %s\n", userName, errmsg ? errmsg : "通用的SQL增删改操作error");
            return -1;
        }
        else
        {
            printf("用户【%s】密码修改成功!\n", userName);
            // 记录日志
            snprintf(message, sizeof(message), "管理员修改了用户【%s】的密码!", userName);
            logToLogInfoTable(db, OPERATELOG, message);
        }
    }
    return 0;
}

/**
 * @description: 管理员服务端通信
 * @param {int} sockfd 套接字
 * @return {*} 成功返回0，失败返回-1
 */
int adminTcpServerCom(int newfd, sqlite3 *db)
{
    // 判断入参
    if (newfd < 0)
    {
        printf("newfd is error");
        return -1;
    }
    int recvCount_admin;
    // int temp_res_admin;
    // char msgToClient_admin[128]; // 接收客户端消息
    char buf_admin[64] = {0};
    int totalReceived_admin = 0; // 接收到的总数据量
    // 接收客户端发来的：业务种类@业务名称
    bzero(buf_admin, sizeof(buf_admin));
    while (totalReceived_admin < sizeof(buf_admin))
    {
        int bytesLeft = sizeof(buf_admin) - totalReceived_admin;
        // recvCount_admin = recv(newfd, buf_admin, sizeof(buf_admin), 0);
        recvCount_admin = recv(newfd, buf_admin + totalReceived_admin, bytesLeft, 0);
        if (recvCount_admin > 0)
        {
            totalReceived_admin += recvCount_admin;
            // 当接收到的数据量达到缓冲区大小时，手动添加结束符
            if (totalReceived_admin >= sizeof(buf_admin))
            {
                buf_admin[sizeof(buf_admin) - 1] = '\0'; // 强制结束符
            }
            // buf[totalReceived] = '\0'; // 确保字符串以 '\0' 结束
            // attempts = 0; // Reset attempts on successful receive
            printf("recvCount_admin: %d, totalReceived_admin: %d\n", recvCount_admin, totalReceived_admin);
        }
        else if (0 == recvCount_admin)
        {
            printf("客户端选择退出!\n");
            return -1;
        }
        else if (recvCount_admin < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                // 没有数据可读取，继续等待其他事件
                usleep(1000); // 等待一小段时间后再继续尝试接收
                continue;     // 继续下一轮循环，等待更多数据
            }
            else
            {
                perror("adminSys recv error");
                return -1; // 处理其他错误
            }
        }
    }
    // 这里需要确保你在后续操作中处理字符串时避免超出
    printf("adminSys Final buf: %s\n", buf_admin); // 打印最终的 buf 内容
    printf("adminSys recvCount_admin = %d\n", totalReceived_admin);
    printf("adminSys接收业务种类@业务名称,成功! buf_admin = %s\n", buf_admin);
    // 解析数据
    char *res[4] = {NULL};
    if (totalReceived_admin == 0 || buf_admin[0] == '\0')
    {
        printf("接收到的 buf 为空，终止操作。\n");
        return -1;
    }
    parseStringUtil(buf_admin, res);
    printf("adminSys业务数据解析成功!\n");
    // 按照业务名称进行模块处理
    // 人工查验审核业务
    if ((0 == strncasecmp(res[0], "admin", 5)) && (0 == strncasecmp(res[1], "checked", 7)))
    {
        // 调用人工查验审核接口
        // manualAudit(db);
        printf("管理员执行了【人工查验审核】操作!\n");
    }
    // 查询操作记录业务
    else if ((0 == strncasecmp(res[0], "admin", 5)) && (0 == strncasecmp(res[1], "select", 6)))
    {
        // 调用查询操作记录接口
        // queryOperationRecord(db);
        printf("管理员执行了【查询操作记录】操作!\n");
    }
    // 修改用户密码业务
    else if ((0 == strncasecmp(res[0], "admin", 5)) && (0 == strncasecmp(res[1], "upPasswd", 8)))
    {
        // 调用修改用户密码接口
        // changeUserPasswd(db);
        printf("管理员执行了【修改用户密码】操作!\n");
    }
    // 退出管理员平台业务
    else if ((0 == strncasecmp(res[0], "admin", 5)) && (0 == strncasecmp(res[1], "quit", 4)))
    {
        printf("管理员退出了登录!\n");
        return -1;
    }
    return 0;
}
